package com.lmaos.basetools.queue3;

import java.lang.reflect.Method;

import com.lmaos.basetools.proxy.MethodIntercept;

public class AsyncIntercept implements MethodIntercept{
	AsyncQueue3 asyncQueue3;
	
	public AsyncIntercept(AsyncQueue3 asyncQueue3) {
		super();
		this.asyncQueue3 = asyncQueue3;
	}
	
	@Override
	public Object invoke(Object obj, Method method, Object[] params)
			throws Throwable {
		Async classAsync = obj.getClass().getAnnotation(Async.class);
		Async methodAsync = method.getAnnotation(Async.class);
		
		String async = getAsyncName(classAsync, methodAsync ,method);
		if(async == null){
			return method.invoke(obj, params);
		}
		AsyncRunnable asyncRunnable = new AsyncRunnable(asyncQueue3, obj, method, params,async);
		asyncQueue3.getThreadPoolExecutor().execute(asyncRunnable);
		Class returnType = method.getReturnType();
		if(Number.class.isAssignableFrom(returnType)){
			return 0;
		}
		if(returnType == int.class||returnType == long.class||returnType == double.class||returnType == float.class||returnType == short.class||returnType == byte.class){
			return 0;
		}
		if(returnType == boolean.class){
			return false;
		}
		if(returnType == char.class){
			return '\0';
		}
		return null;
	}
	
	private String getAsyncName(Async classAsync,Async methodAsync,Method method){
		if(classAsync==null&&methodAsync==null){
			return null;
		}
		StringBuilder name = new StringBuilder(32);
		if(classAsync!=null){
			String classAsyncName = classAsync.value();
			if(!classAsyncName.trim().isEmpty()){
				name.append(name).append("/");
			}
		}
		String methodAsynName = null;
		if(methodAsync!=null){
			methodAsynName = methodAsync.value().trim();
		}
		if(methodAsync == null||methodAsynName.isEmpty()){
			Class[] paramTypes = method.getParameterTypes();
			name.append(methodAsynName);
			if(paramTypes!=null&&paramTypes.length>0){
				name.append("(");
				for (Class paramType : paramTypes) {
					name.append(paramType.getName()).append(",");
				}
				name.replace(name.length()-1, name.length(), ")");
			}
		}else{
			name.append(methodAsynName);
		}
		
		return name.toString();
	}
	
	
}
